package com.example.data.permission.mp.mate;

import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;

import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.BiConsumer;

/**
 * Created by TD on 2021/7/28
 */
public class FieldSetPropertyUtils {

    // 存放实体类以及他们的 字段设置策略
    private static Map<Class<?>, List<FieldSetProperty>> classListMap = new ConcurrentHashMap();
    // 线程安全的 HashSet 存放没有翻译注解的实体类
    private static Set<Class<?>> set = new CopyOnWriteArraySet();


    // 查询 实体类的FieldSetProperty（字段翻译属性）
    public static List<FieldSetProperty> get(Class<?> classZ) {
        if (set.contains(classZ)) {
            return null;
        } else {
            // 获取实体类的FieldSetProperty
            List<FieldSetProperty> setPropertyList = classListMap.get(classZ);
            if (null == setPropertyList) {
                // 如果没查询到，反射获取
                // 判断判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同，或是否是其超类或超接口
                if (classZ.isAssignableFrom(HashMap.class)) {
                    // 如果实体类是 HashMap 直接添加
                    set.add(classZ);
                } else {
                    setPropertyList = new ArrayList();
                    // 获取获得某个类的所有声明的字段，即包括public、private和proteced，但是不包括父类的申明字段
                    Field[] declaredFields = classZ.getDeclaredFields();
                    // 循环是实体类的字段
                    for (int i = 0; i < declaredFields.length; ++i) {
                        // 获取字段
                        Field field = declaredFields[i];

                        // 获取字段上的 FieldDict 注解
                        FieldDict fieldDict = field.getAnnotation(FieldDict.class);
                        if (null != fieldDict) {
                            // 有 fieldDict字段, 创建FieldSetProperty，字段名，FieldDict注解
                            FieldSetProperty fieldSetProperty = new FieldSetProperty(field.getName(), fieldDict);
                            setPropertyList.add(fieldSetProperty);

                        }
                    }

                    if (setPropertyList.isEmpty()) {
                        set.add(classZ);
                    } else {
                        classListMap.put(classZ, setPropertyList);
                    }
                }
            }

            return setPropertyList;
        }
    }

/*    public static boolean O000000o(Configuration var0, Object var1, BiConsumer<MetaObject, FieldSetProperty> var2) {
        List var3 = O00000Oo(var1.getClass());
        if (classListMap.O00000Oo(var3)) {
            MetaObject var4 = var0.newMetaObject(var1);
            var3.parallelStream().forEach((var2x) -> {
                var2.accept(var4, var2x);
            });
            return true;
        } else {
            return false;
        }
    }

    *//**
     *
     * @param var0
     * @param var1
     * @param var2
     * @return
     *//*
    public static boolean O00000Oo(Configuration var0, Object var1, BiConsumer<MetaObject, FieldSetProperty> var2) {
        List var3 = O00000Oo(var1.getClass());
        if (classListMap.O00000Oo(var3) && var3.stream().anyMatch((var0x) -> {
            return null != var0x.getFieldEncrypt();
        })) {
            MetaObject var4 = var0.newMetaObject(var1);
            var3.stream().filter((var0x) -> {
                return null != var0x.getFieldEncrypt();
            }).forEach((var2x) -> {
                var2.accept(var4, var2x);
            });
            return true;
        } else {
            return false;
        }
    }*/
}
